package com.echoesnet.echoesshortvideo.Utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.os.Environment;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.echoesnet.echoesshortvideo.AppController;
import com.echoesnet.echoesshortvideo.Utils.ImageUtils.ImageUtils;
import com.github.hiteshsondhi88.libffmpeg.FFmpeg;
import com.github.hiteshsondhi88.libffmpeg.FFmpegExecuteResponseHandler;
import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegCommandAlreadyRunningException;
import com.liulishuo.okdownload.DownloadTask;
import com.liulishuo.okdownload.core.cause.EndCause;
import com.liulishuo.okdownload.core.cause.ResumeFailedCause;
import com.liulishuo.okdownload.core.listener.DownloadListener1;
import com.liulishuo.okdownload.core.listener.assist.Listener1Assist;
import com.orhanobut.logger.Logger;

import java.io.File;
import java.io.FileOutputStream;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import wseemann.media.FFmpegMediaMetadataRetriever;

/**
 * Copyright (C) 2017 在线回声（天津）科技发展有限公司
 * 在线回声完全享有此软件的著作权，违者必究
 *
 * @author an
 * @version 1.0
 * @modifier
 * @createDate 2018/4/23 0023
 * @description
 */
public class VideoUtils
{
    private static final String TAG = VideoUtils.class.getSimpleName();
    /**
     * 应用版本名称
     */
    private static String mAppVersionName;
    /**
     * 应用版本号
     */
    private static int mAppVersionCode;

    /**
     * 初始化SDK
     */
    public static void initialize(Context context)
    {
        mAppVersionName = CommonUtils.getVerName(context);
        mAppVersionCode = CommonUtils.getVerCode(context);
    }


    /**
     * 获取视频缩略图
     *
     * @param time              需要获取时间点
     * @param path              视频路径
     * @param output            缩略图输出路径
     * @param videoUtilListener
     */
    public static void getVideoMediaThumbnail(long time, int degree, String path, String output, float rotation, boolean isOriginal,
                                              VideoUtilListener videoUtilListener)
    {
        File file = new File(output);
        if (!file.getParentFile().exists())
            file.getParentFile().mkdirs();
        Logger.t(TAG).d("parent>>" + file.getParent());
//        Observable.create(new ObservableOnSubscribe<String>()
//        {
//            @Override
//            public void subscribe(ObservableEmitter<String> o) throws Exception
//            {
//                Log.d(TAG, "开始获取缩略图 path>>" + path + "| output>>" + output);
//                File file1 = new File(output);
//                if (!file1.exists()) // 如果存在不重新截图
//                {
//                    StringBuilder sb = new StringBuilder("ffmpeg");
//                    sb.append(" -ss");
//                    sb.append(" " + time);
//                    sb.append(" -i");
//                    sb.append(" " + path);
//                    sb.append(" -f");
//                    sb.append(" image2");
//                    if (!isOriginal)
//                    {
//                        sb.append(" -s");
//                        sb.append(" 100x100");
//                    }
//                    sb.append(" " + output);
//                    Log.d(TAG, "命令>>>>>" + sb.toString());
//                    int b = UtilityAdapter.FFmpegRun("", sb.toString());
//                    Log.d(TAG, sb.toString() + "| result>>" + b);
//                }
//                if (degree != 0)
//                    CommonUtils.rotaingImageView(degree, output);
//                Logger.t(TAG).d("output>>>>>>>>>" + output);
//                o.onNext(output);
//            }
//        }).subscribeOn(Schedulers.single())
//                .unsubscribeOn(Schedulers.io())
//                .observeOn(AndroidSchedulers.mainThread())
//                .subscribe(new Consumer<String>()
//                {
//                    @Override
//                    public void accept(String s) throws Exception
//                    {
//                        if (videoUtilListener != null)
//                            videoUtilListener.complete(output, "");
//                    }
//                }, new Consumer<Throwable>()
//                {
//                    @Override
//                    public void accept(Throwable throwable) throws Exception
//                    {
//                        Logger.t(TAG).d("获取缩略图失败>>" + throwable.getMessage());
//                    }
//                });

        Observable.create(new ObservableOnSubscribe<String>()
        {
            @Override
            public void subscribe(ObservableEmitter<String> o) throws Exception
            {
                Bitmap bitmap = null;
                FFmpegMediaMetadataRetriever retriever = new FFmpegMediaMetadataRetriever();
                try {
                    retriever.setDataSource(path);
                    int with = 60;
                    int height = 120;
                    if (rotation == 90 || rotation == 270)
                    {
                        int temp = with;
                        with = height;
                        height = temp;
                    }
                    if (isOriginal)
                    {
                        bitmap = retriever.getFrameAtTime(1000 * time, MediaMetadataRetriever.OPTION_CLOSEST);
                    }else {
                        bitmap = retriever.getScaledFrameAtTime(1000 * time, MediaMetadataRetriever.OPTION_CLOSEST,with,height);
                    }
                    bitmap = ImageUtils.rotateImageView(rotation,bitmap);
                }
                catch(IllegalArgumentException e) {
                    e.printStackTrace();
                }
                catch (RuntimeException e) {
                    e.printStackTrace();
                }
                finally {
                    try {
                        retriever.release();
                    }
                    catch (RuntimeException e) {
                        e.printStackTrace();
                    }
                }
                FileOutputStream fos = null;
                try {
                    fos = new FileOutputStream(output);
                    if (fos != null) {
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                        fos.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                o.onNext(output);
            }
        }).subscribeOn(Schedulers.computation())
                .unsubscribeOn(Schedulers.computation())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<String>()
                {
                    @Override
                    public void accept(String s) throws Exception
                    {
                        if (videoUtilListener != null)
                            videoUtilListener.complete(output,"");
                    }
                });

    }

    /**
     * 剪切视频
     *
     * @param startTime         开始时间
     * @param endTime           结束时间
     * @param path              视频路径
     * @param output            视频输出路径
     * @param videoUtilListener 完成监听
     */
    public static void cutVideo(String startTime, String endTime, String path, String output,
                                VideoUtilListener videoUtilListener)
    {
        File file = new File(output);
        if (!file.getParentFile().exists())
            file.getParentFile().mkdirs();
        // -ss 00:00:01 -t 00:00:09 -i /storage/emulated/0/joke_essay/1517299117596.mp4 -c:v libx264 -c:a aac -strict experimental -b:a 98k /storage/emulated/0/EatAndMeet/CutVideo/1517383378160.mp4
        long startCutTime = System.currentTimeMillis();
//        Observable.create(new ObservableOnSubscribe<String>()
//        {
//            @Override
//            public void subscribe(ObservableEmitter<String> emitter) throws Exception
//            {
//                StringBuilder sb = new StringBuilder("ffmpeg");
//                sb.append(" -r 20 -ss");
//                sb.append(" " + startTime);
//                sb.append(" -t");
//                sb.append(" " + endTime);
//                sb.append(" " + path);
//                sb.append(" -c:v h264 -c:a aac -strict experimental -b:a 1000k");
//                sb.append(" " + output);
//                Logger.t(TAG).d("cut video start >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> " + sb);
//                int i = UtilityAdapter.FFmpegRun("", sb.toString());
//                Logger.t(TAG).d("sb>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + sb + "| result >>" + i);
//                emitter.onNext(output);
//            }
//        }).subscribeOn(Schedulers.single())
//                .observeOn(AndroidSchedulers.mainThread())
//                .subscribe(new Consumer<String>()
//                {
//                    @Override
//                    public void accept(String s) throws Exception
//                    {
//                        Logger.t(TAG).d("剪切结束 用时>>>>" + (System.currentTimeMillis() - startCutTime));
//                        if (videoUtilListener != null)
//                            videoUtilListener.complete(output, "");
//                    }
//                }, new Consumer<Throwable>()
//                {
//                    @Override
//                    public void accept(Throwable throwable) throws Exception
//                    {
//                        Logger.t(TAG).d("剪切异常 用时>>>>" + (System.currentTimeMillis() - startCutTime));
//                        if (videoUtilListener != null)
//                            videoUtilListener.complete(output, throwable.getMessage());
//                    }
//                });
        FFmpeg fFmpeg = FFmpeg.getInstance(AppController.getInstance());
        Logger.t(TAG).d("cut video start >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> " );
        StringBuilder cutVideoSb = new StringBuilder();
        cutVideoSb.append("-ss");
        cutVideoSb.append(" " + startTime);
        cutVideoSb.append(" -t");
        cutVideoSb.append(" " + endTime);
        cutVideoSb.append(" -i");
        cutVideoSb.append(" " + path);
        cutVideoSb.append(" -c:v libx264 -c:a aac -preset ultrafast -crf 32 -y -strict experimental -acodec libmp3lame -ab 128k");
        cutVideoSb.append(" " + output);
        Logger.t(TAG).d("sb>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + cutVideoSb);
        long start = System.currentTimeMillis();
        try
        {
            String finalOutput = output;
            fFmpeg.execute(cutVideoSb.toString().split(" "), new FFmpegExecuteResponseHandler()
            {
                @Override
                public void onSuccess(String message)
                {
                    Logger.t(TAG).d("onSuccess 用时>>>>" + (System.currentTimeMillis() - startCutTime));
                }

                @Override
                public void onProgress(String message)
                {
                    Logger.t(TAG).d("剪切视频onProgress>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + message);
                }

                @Override
                public void onFailure(String message)
                {
                    Logger.t(TAG).d("剪切异常 用时>>>>" + (System.currentTimeMillis() - startCutTime));
                    if (videoUtilListener != null)
                        videoUtilListener.complete(output, message);
                }

                @Override
                public void onStart()
                {
                    Logger.t(TAG).d("剪切视频onStart>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                    if (videoUtilListener != null)
                        videoUtilListener.start();
                }

                @Override
                public void onFinish()
                {
                    Logger.t(TAG).d("剪切结束 用时>>>>" + (System.currentTimeMillis() - startCutTime));
                    if (videoUtilListener != null)
                        videoUtilListener.complete(output, "");
                }
            });
        } catch (FFmpegCommandAlreadyRunningException e)
        {
            if (videoUtilListener != null)
                videoUtilListener.complete("",e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 压缩视频
     *
     * @param path              视频路径
     * @param output            视频输出路径
     * @param videoUtilListener 完成监听
     */
    public static void compressVideo(String path, String output,
                                     VideoUtilListener videoUtilListener)
    {
        File file = new File(output);
        if (!file.getParentFile().exists())
            file.getParentFile().mkdirs();
        // -ss 00:00:01 -t 00:00:09 -i /storage/emulated/0/joke_essay/1517299117596.mp4 -c:v libx264 -c:a aac -strict experimental -b:a 98k /storage/emulated/0/EatAndMeet/CutVideo/1517383378160.mp4
        long startCutTime = System.currentTimeMillis();
//        Observable.create(new ObservableOnSubscribe<String>()
//        {
//            @Override
//            public void subscribe(ObservableEmitter<String> emitter) throws Exception
//            {
//                Logger.t(TAG).d("cut video start >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ");
//                StringBuilder sb = new StringBuilder("ffmpeg");
//                sb.append(" -i");
//                sb.append(" " + path);
//                sb.append(" -c:v h264 -c:a aac -strict experimental -b 900k");
//                sb.append(" " + output);
//                int i = UtilityAdapter.FFmpegRun("", sb.toString());
//                Logger.t(TAG).d("压缩>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + sb + "| result >>" + i);
//                long size = CommonUtils.getFileSize(new File(output));
//                Logger.t(TAG).d("size >>>>>>" + size);
//                if (size <= 0)
//                    Thread.sleep(2000);
//                emitter.onNext(size > 0 ? output : path);
//            }
//        }).subscribeOn(Schedulers.single())
//                .observeOn(AndroidSchedulers.mainThread())
//                .subscribe(new Consumer<String>()
//                {
//                    @Override
//                    public void accept(String s) throws Exception
//                    {
//                        Logger.t(TAG).d("压缩结束 用时>>>>" + (System.currentTimeMillis() - startCutTime));
//                        if (videoUtilListener != null)
//                            videoUtilListener.complete(s, "");
//                    }
//                }, new Consumer<Throwable>()
//                {
//                    @Override
//                    public void accept(Throwable throwable) throws Exception
//                    {
//                        Logger.t(TAG).d("压缩异常 用时>>>>" + (System.currentTimeMillis() - startCutTime));
//                        if (videoUtilListener != null)
//                            videoUtilListener.complete(path, throwable.getMessage());
//                    }
//                });
        FFmpeg fFmpeg = FFmpeg.getInstance(AppController.getInstance());
        Logger.t(TAG).d("cut video start >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> " );
        StringBuilder cutVideoSb = new StringBuilder();
        cutVideoSb.append("-i");
        cutVideoSb.append(" " + path);
        cutVideoSb.append(" -c:v libx264 -c:a aac -preset ultrafast -crf 32 -y -strict experimental -acodec libmp3lame -ab 128k");
        cutVideoSb.append(" " + output);
        Logger.t(TAG).d("sb>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + cutVideoSb);
        long start = System.currentTimeMillis();
        try
        {
            String finalOutput = output;
            fFmpeg.execute(cutVideoSb.toString().split(" "), new FFmpegExecuteResponseHandler()
            {
                @Override
                public void onSuccess(String message)
                {
                    Logger.t(TAG).d("onSuccess 用时>>>>" + (System.currentTimeMillis() - startCutTime));
                }

                @Override
                public void onProgress(String message)
                {
                    Logger.t(TAG).d("压缩视频onProgress>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + message);
                }

                @Override
                public void onFailure(String message)
                {
                    Logger.t(TAG).d("压缩异常 用时>>>>" + (System.currentTimeMillis() - startCutTime) + message);
                }

                @Override
                public void onStart()
                {
                    Logger.t(TAG).d("压缩视频onStart>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                    if (videoUtilListener != null)
                        videoUtilListener.start();
                }

                @Override
                public void onFinish()
                {
                    Logger.t(TAG).d("压缩结束 用时>>>>" + (System.currentTimeMillis() - startCutTime));
                  long size = CommonUtils.getFileSize(new File(output));
                Logger.t(TAG).d("size >>>>>>" + size);
                if (size <= 0)
                    new Handler().postDelayed(new Runnable()
                    {
                        @Override
                        public void run()
                        {
                            if (videoUtilListener != null)
                                videoUtilListener.complete(size > 0 ? output : path, "");
                        }
                    },2000);
                else if (videoUtilListener != null)
                        videoUtilListener.complete(size > 0 ? output : path, "");
                }
            });
        } catch (FFmpegCommandAlreadyRunningException e)
        {
            if (videoUtilListener != null)
                videoUtilListener.complete("",e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 左右翻转视频
     *
     * @param path              视频路径
     * @param output            视频输出路径
     * @param videoUtilListener 完成监听
     */
    public static void reversalVideo(String path, String output,
                                     VideoUtilListener videoUtilListener)
    {
        File file = new File(output);
        if (!file.getParentFile().exists())
            file.getParentFile().mkdirs();
        // -ss 00:00:01 -t 00:00:09 -i /storage/emulated/0/joke_essay/1517299117596.mp4 -c:v libx264 -c:a aac -strict experimental -b:a 98k /storage/emulated/0/EatAndMeet/CutVideo/1517383378160.mp4
        long startCutTime = System.currentTimeMillis();
//        Observable.create(new ObservableOnSubscribe<String>()
//        {
//            @Override
//            public void subscribe(ObservableEmitter<String> emitter) throws Exception
//            {
//                Logger.t(TAG).d("cut video start >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ");
//                StringBuilder sb = new StringBuilder("ffmpeg");
//                sb.append(" -i");
//                sb.append(" " + path);
//                sb.append(" -vf hflip -sameq -ar 44100");
//                sb.append(" " + output);
//                int i = UtilityAdapter.FFmpegRun("", sb.toString());
//                Logger.t(TAG).d("翻转视频>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + sb + "| result >>" + i);
//                long size = CommonUtils.getFileSize(new File(output));
//                Logger.t(TAG).d("size >>>>>>" + size);
//                if (size <= 0)
//                    Thread.sleep(2000);
//                emitter.onNext(size > 0 ? output : path);
//            }
//        }).subscribeOn(Schedulers.single())
//                .observeOn(AndroidSchedulers.mainThread())
//                .subscribe(new Consumer<String>()
//                {
//                    @Override
//                    public void accept(String s) throws Exception
//                    {
//                        Logger.t(TAG).d("翻转视频 用时>>>>" + (System.currentTimeMillis() - startCutTime));
//                        if (videoUtilListener != null)
//                            videoUtilListener.complete(s, "");
//                    }
//                }, new Consumer<Throwable>()
//                {
//                    @Override
//                    public void accept(Throwable throwable) throws Exception
//                    {
//                        Logger.t(TAG).d("翻转视频 用时>>>>" + (System.currentTimeMillis() - startCutTime));
//                        if (videoUtilListener != null)
//                            videoUtilListener.complete(path, throwable.getMessage());
//                    }
//                });

        FFmpeg fFmpeg = FFmpeg.getInstance(AppController.getInstance());
        Logger.t(TAG).d("cut video start >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> " );
        StringBuilder cutVideoSb = new StringBuilder();
        cutVideoSb.append(" -i");
        cutVideoSb.append(" " + path);
        cutVideoSb.append(" -c:v libx264 -c:a aac -vf hflip -preset ultrafast -crf 32 -y -strict experimental -acodec libmp3lame -ab 128k");
        cutVideoSb.append(" " + output);
        Logger.t(TAG).d("sb>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + cutVideoSb);
        long start = System.currentTimeMillis();
        try
        {
            String finalOutput = output;
            fFmpeg.execute(cutVideoSb.toString().split(" "), new FFmpegExecuteResponseHandler()
            {
                @Override
                public void onSuccess(String message)
                {
                    Logger.t(TAG).d("onSuccess 用时>>>>" + (System.currentTimeMillis() - startCutTime));
                }

                @Override
                public void onProgress(String message)
                {
                    Logger.t(TAG).d("翻转视频onProgress>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + message);
                }

                @Override
                public void onFailure(String message)
                {
                    Logger.t(TAG).d("翻转视频 用时>>>>" + (System.currentTimeMillis() - startCutTime));
                    if (videoUtilListener != null)
                        videoUtilListener.complete(output, message);
                }

                @Override
                public void onStart()
                {
                    Logger.t(TAG).d("翻转视频onStart>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                    if (videoUtilListener != null)
                        videoUtilListener.start();
                }

                @Override
                public void onFinish()
                {
                    Logger.t(TAG).d("压缩结束 用时>>>>" + (System.currentTimeMillis() - startCutTime));
                    if (videoUtilListener != null)
                        videoUtilListener.complete(output, "");
                }
            });
        } catch (FFmpegCommandAlreadyRunningException e)
        {
            if (videoUtilListener != null)
                videoUtilListener.complete("",e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 获取视频缩略图
     *
     * @param time              需要获取时间点
     * @param path              视频路径
     * @param output            缩略图输出路径
     * @param videoUtilListener
     */
    public static void getMediaThumbnail(int time, String path, String output, float rotation, boolean isOriginal,
                                         VideoUtilListener videoUtilListener)
    {
        Observable.create(new ObservableOnSubscribe<String>()
        {
            @Override
            public void subscribe(ObservableEmitter<String> o) throws Exception
            {
                Bitmap bitmap = null;
                FFmpegMediaMetadataRetriever retriever = new FFmpegMediaMetadataRetriever();
                try
                {
                    retriever.setDataSource(path);
                    int with = 60;
                    int height = 120;
                    if (rotation == 90 || rotation == 270)
                    {
                        int temp = with;
                        with = height;
                        height = temp;
                    }
                    if (isOriginal)
                    {
                        bitmap = retriever.getFrameAtTime(1000000 * time, MediaMetadataRetriever.OPTION_CLOSEST);
                    } else
                    {
                        bitmap = retriever.getScaledFrameAtTime(1000000 * time, MediaMetadataRetriever.OPTION_CLOSEST, with, height);
                    }
                    bitmap = ImageUtils.rotateImageView(rotation, bitmap);
                } catch (IllegalArgumentException e)
                {
                    e.printStackTrace();
                } catch (RuntimeException e)
                {
                    e.printStackTrace();
                } finally
                {
                    try
                    {
                        retriever.release();
                    } catch (RuntimeException e)
                    {
                        e.printStackTrace();
                    }
                }
                FileOutputStream fos = null;
                try
                {
                    fos = new FileOutputStream(output);
                    if (fos != null)
                    {
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                        fos.close();
                    }
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
                Logger.t(TAG).d("读取旋转角度>>>" + CommonUtils.getExifOrientation(output));
                o.onNext(output);
            }
        }).subscribeOn(Schedulers.computation())
                .unsubscribeOn(Schedulers.computation())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<String>()
                {
                    @Override
                    public void accept(String s) throws Exception
                    {
                        if (videoUtilListener != null)
                            videoUtilListener.complete(output, "");
                    }
                });


    }

    public static String getDuration(String mUri){
        String duration = null;
        FFmpegMediaMetadataRetriever mediaMetadataRetriever = new FFmpegMediaMetadataRetriever();
        try
        {
            mediaMetadataRetriever.setDataSource(mUri);
            duration = mediaMetadataRetriever.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION);
        } catch (IllegalArgumentException e)
        {
            e.printStackTrace();
        } finally
        {
            mediaMetadataRetriever.release();
        }
        Logger.t(TAG).d("duration>>>" + duration);
        return duration;
    }


    public static void saveVideoToMediaLib(Context context,String videoUrl)
    {
        String fileName = videoUrl.substring(
                videoUrl.lastIndexOf("/") + 1, videoUrl.length()
        );
        String filePath= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath()+"/Camera";
        File download = new File(filePath
//                            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath(),
//                            "Camera"
        );
        if (!download.exists())
        {
            download.mkdir();
        }
        DownLoadUtil.getInstance().downloadFile(videoUrl, filePath, fileName, new DownloadListener1()
        {
            @Override
            public void taskStart(@NonNull DownloadTask task, @NonNull Listener1Assist.Listener1Model model)
            {
                ToastUtils.showShort("开始下载...");
            }

            @Override
            public void retry(@NonNull DownloadTask task, @NonNull ResumeFailedCause cause)
            {
                ToastUtils.showShort("重试中...");
            }

            @Override
            public void connected(@NonNull DownloadTask task, int blockCount, long currentOffset, long totalLength)
            {

            }

            @Override
            public void progress(@NonNull DownloadTask task, long currentOffset, long totalLength)
            {

            }

            @Override
            public void taskEnd(@NonNull DownloadTask task, @NonNull EndCause cause, @Nullable Exception realCause, @NonNull Listener1Assist.Listener1Model model)
            {
                if ("COMPLETED".equals(cause.name()))
                {
                    CommonUtils.insertIntoMediaStore(context, true, task.getFile().getPath(), 0);
                    ToastUtils.showLong("已保存至：" + task.getFile().getPath());
                }
            }
        });
    }
}